Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uniformize kwargs for Idefics/2 processors #32568

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

yonigozlan
Copy link
Member

@yonigozlan yonigozlan commented Aug 9, 2024

What does this PR do?

Adds uniformized processors kwargs following #31911 for the following models:

  • Idefics
  • Idefics2

Before submitting

  • This PR fixes a typo or improves the docs (you can dismiss the other checks if that's the case).
  • Did you read the contributor guideline,
    Pull Request section?
  • Was this discussed/approved via a Github issue or the forum? Please add a link
    to it if that's the case.
  • Did you make sure to update the documentation with your changes? Here are the
    documentation guidelines, and
    here are tips on formatting docstrings.
  • Did you write any new necessary tests?

Who can review?

@molbap @zucchini-nlp @amyeroberts

@yonigozlan yonigozlan mentioned this pull request Aug 9, 2024
40 tasks
@yonigozlan yonigozlan marked this pull request as ready for review August 9, 2024 16:14
@HuggingFaceDocBuilderDev

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

Comment on lines 329 to 365
# for BC
if text is None:
# if the user didn't specify text=text in the call, we assume they want to use the old behavior
# with text (previously prompts) as a first argument
warnings.warn(
"The use of `text` as the first argument will be deprecated in the future. `images` is now the first argument."
"The first given argument will be considered as `prompts` in the old behavior.",
)
text = images
images = None
if images is None:
# assuming the user wants to use the old behavior with prompts as the only argument
prompts = text
elif text is not None:
# Assuming image-text-to-text behavior:
# Check if batched images are provided
if not isinstance(images, (list, tuple)):
images = [images]
if isinstance(text, str):
# one prompt for all images instead of one prompt per image
text = [text] * len(images)
# Check if batched text is provided
if isinstance(text, (list, tuple)) and len(text) != len(images):
raise ValueError(
"When using the image-text-to-text behavior, the number of prompts should be the same as the number of images."
)
# Check that only text is present in the prompts
if not all(isinstance(i, str) for i in text):
raise ValueError("When using the image-text-to-text behavior, the prompts should only contain text.")
prompts = list(zip(images, text))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of logic is needed for backward compatibility, as idefics used to take only prompts where text and images inputs would be interleaved. This added logic preserve supports for these kind of inputs (where prompts is replaced by text arg), while adding support for usual text and images inputs as in other image-text-to-text models. This will also be useful to support idefics in the image-text-to-text pipeline.

@yonigozlan yonigozlan mentioned this pull request Aug 10, 2024
5 tasks
Copy link
Member

@zucchini-nlp zucchini-nlp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also looks good to me. Just want to clarify what will be the new format for Idefics to make the pipeline happy. Maybe we can add a test for that new format :)

Comment on lines 347 to 349
if isinstance(text, str):
# one prompt for all images instead of one prompt per image
text = [text] * len(images)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this code block is for new processing behavior when users pass images and text.

Not very sure this is a good idea to repeat text several times. Suppose user has one prompt with interleaved images-text, then we would replicate the prompt several times and cause error in downstream modeling code. For ex:

processor(text=["User: What do you see here? Assistant: a cat. User: what about this image?"], images=[image1, image2])

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that's a good point. Although interleaved images-text is not really supported when providing both images and text for Idefics, as there is no way to indicate where to put the images in the prompt. Maybe I should add a warning here instead of automatically duplicating the prompts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see now, indeed Idefics is a bit peculiar.

Yes interleaving like that is not, but providing more than 1 image per prompt like in multi-turn conversation is okey, as in the dosctring of call method. Then we should expect users to pass as many images as prompts, and they would have to wrap images as a batched list if there's more than one per prompt.

I think we can even raise an error, as we cannot know for sure what is the user expecting with these inputs. An error explaining what kind of input we want and let the user fix it, otherwise users who never read warnings might start complaining in the issues :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added support for multiple images per prompt, and this warning to make it clearer what input format we expect when using image-text-to-text format:

# Check if batched images and text are in the correct format
if isinstance(text, (list, tuple)) and len(text) != len(images):
raise ValueError(
"When providing both images and text arguments, the number of text prompts should be the same as the number of images."
"If you want to have several images per prompt, images should be nested as such: images=[[img1, img2], [img3, img4], ...] for text=[prompt1, prompt2, ...]."
)

tests/models/idefics/test_processor_idefics.py Outdated Show resolved Hide resolved
def test_tokenizer_defaults_preserved_by_kwargs(self):
if "image_processor" not in self.processor_class.attributes:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imo we don't have to overwrite all tests for idefics, seems quite similar to the general test from mixin except for padding="max_length". We can and maybe should indicate padding="max_length" in mixin tests, cause we can't assume all tokenizer will default to "max_length" padding

@yonigozlan yonigozlan force-pushed the uniformize-processors-kwargs-idefics-idefics2 branch from 9799303 to 8b171a7 Compare August 14, 2024 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants